﻿// <author>Netmon Cipher Dev Team</author>
// <date>2009-06-16</date>
// <version>1.0</version>
// <summary>This contains the variables used in Decryption.</summary>

namespace SSLDecryptionExpert
{
    using System;

    #region Current State
    /// <summary>
    /// Indicates the current state of SSL message sequence
    /// while Enumerating the capture.
    /// </summary>
    public enum CurrentState
    {
        /// <summary>
        /// Initial State
        /// </summary>
        Initial,

        /// <summary>
        /// Client Hello State
        /// </summary>
        ClientHello,

        /// <summary>
        /// Client Hello Finished
        /// </summary>
        ClientHelloDone,

        /// <summary>
        /// Server Hello State
        /// </summary>
        ServerHello,

        /// <summary>
        /// Server Hello Finished
        /// </summary>
        ServerHelloDone,

        /// <summary>
        /// Client Key Exchange Field
        /// </summary>
        ClientKeyExchange,

        /// <summary>
        /// Client Key Exchange Finished
        /// </summary>
        ClientKeyExchangeDone,

        /// <summary>
        /// Change Cipher Spec State
        /// </summary>
        ChangeCipher,

        /// <summary>
        /// Application Data Exchange State
        /// </summary>
        ApplicationData,

        /// <summary>
        /// Application Data Exchange Finished
        /// </summary>
        ApplicationDataDone
    }
    
    #endregion    

    #region CipherSuites Enum

    /// <summary>
    /// Enumeration for ciphersuites.
    /// </summary>
    public enum CipherSuite : int
    {
        /// <summary>
        /// Cipher TLS_RSA_WITH_NULL_MD5
        /// </summary>
        TLS_RSA_WITH_NULL_MD5 = 0x01,

        /// <summary>
        /// Cipher TLS_RSA_WITH_NULL_SHA
        /// </summary>
        TLS_RSA_WITH_NULL_SHA = 0x02,

        /// <summary>
        /// Cipher TLS_RSA_WITH_RC4_128_MD5
        /// </summary>
        TLS_RSA_WITH_RC4_128_MD5 = 0x04,

        /// <summary>
        /// Cipher TLS_RSA_WITH_RC4_128_SHA
        /// </summary>
        TLS_RSA_WITH_RC4_128_SHA = 0x05,
        
        /// <summary>
        /// Cipher TLS_RSA_WITH_3DES_EDE_CBC_SHA
        /// </summary>
        TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x0A,        

        /// <summary>
        /// Cipher TLS_RSA_WITH_AES_128_CBC_SHA
        /// </summary>
        TLS_RSA_WITH_AES_128_CBC_SHA = 0x2F,

        /// <summary>
        /// Cipher TLS_RSA_WITH_AES_256_CBC_SHA
        /// </summary>
        TLS_RSA_WITH_AES_256_CBC_SHA = 0x35,

        /// <summary>
        /// Cipher SSL2_RC4_128_MD5
        /// </summary>
        SSL2_RC4_128_MD5 = 0x10080,

        /// <summary>
        /// Cipher: SSL2_DES_192_EDE3_CBC_WITH_MD5
        /// </summary>
        SSL2_DES_192_EDE3_CBC_WITH_MD5 = 0x700C0
    }

    #endregion

    #region Data Encryption Methods Enum

    /// <summary>
    /// Enumeration for Data Encryption Methods
    /// </summary>
    public enum DataEncryptionMethod
    {
        /// <summary>
        /// NULL or No Decryption
        /// </summary>
        NULL,

        /// <summary>
        /// 3DES + EDE
        /// </summary>
        DES3_EDE,

        /// <summary>
        /// AES 128 bit
        /// </summary>
        AES128,

        /// <summary>
        /// AES 256 bit
        /// </summary>
        AES256,

        /// <summary>
        /// RC4 128 bit
        /// </summary>
        RC4_128
    }

    #endregion

    #region CipherMode Enum

    /// <summary>
    /// Cipher mode to select the cipher suite
    /// </summary>
    public enum CipherMode
    {
        /// <summary>
        /// CipherMode CBC
        /// </summary>
        CBC,

        /// <summary>
        /// CipherMode CTS
        /// </summary>
        CTS,

        /// <summary>
        /// CipherMode None
        /// </summary>
        None
    }

    #endregion

    #region Key Exchange Algorithm Enum

    /// <summary>
    /// Enumeration for Key Exchange Algorithms
    /// </summary>
    public enum KeyExchangeAlgorithm
    {
        /// <summary>
        /// RSA Key Exchange Algorithm
        /// </summary>
        RSA,

        /// <summary>
        /// DHE Key Exchange Algorithm
        /// </summary>
        DHE
    }

    #endregion

    #region MAC Enum

    /// <summary>
    /// Enumeration for MAC
    /// </summary>
    public enum MAC
    {
        /// <summary>
        /// MAC type MD5
        /// </summary>
        MD5,

        /// <summary>
        /// MAC type SHA1
        /// </summary>
        SHA1
    }

    #endregion

    #region Cipher Block Size Enum

    /// <summary>
    /// Bit-string size of Cipher in bytes
    /// </summary>
    public enum CipherBlockSize
    {
        /// <summary>
        /// AES Bit-String Size
        /// </summary>
        AES = 16,

        /// <summary>
        /// DES Bit-String size
        /// </summary>
        DES = 8,

        /// <summary>
        /// No Bit-String Size used for Stream Cipher
        /// </summary>
        NULL = 0
    }

    #endregion

    #region Status Enum

    /// <summary>
    /// Enum for Operation Status 
    /// </summary>
    public enum Status : int
    {
        /// <summary>
        /// Returned by API functions when they are successful.
        /// </summary>
        ERROR_SUCCESS = 0,

        /// <summary>
        /// Reference to a file, file path, handle, or data field is incorrect.
        /// </summary>
        ERROR_NOT_FOUND = 1168,

        /// <summary>
        /// The field is a container, so the content is not available.
        /// </summary>
        ERROR_RESOURCE_NOT_AVAILABLE = 5006
    }

    #endregion

    //// TODO: Remove This Class / Make Non-static
    /// <summary>
    /// Variables used in Decryption.
    /// </summary>
    public class Variables
    {
        /// <summary>
        /// Object of Logger Class to log process information.
        /// </summary>
        public static Logger Log;

        #region Variables to store IP Addresses

        /// <summary>
        /// to store certificate file path.
        /// </summary>
        public static string clientIP;

        /// <summary>
        /// to store certificate file path.
        /// </summary>
        public static string serverIP;

        /// <summary>
        /// Store the IPv6 Address.
        /// </summary>
        public static byte[] IPv6SourceAddress = new byte[16];

        /// <summary>
        /// Store the IPv6 Address.
        /// </summary>
        public static byte[] IPv6DestinationAddress = new byte[16];

        /// <summary>
        /// Store the IPv4 Address.
        /// </summary>
        public static byte[] IPv4SourceAddress = new byte[4];

        /// <summary>
        /// Store the IPv4 Address.
        /// </summary>
        public static byte[] IPv4DestinationAddress = new byte[4];

        #endregion

        #region Variables to store Port Numbers

        /// <summary>
        /// Checks is data is from Client
        /// </summary>
        public static bool isSourceClient;        

        /// <summary>
        /// Stores Source Port Number
        /// </summary>
        public static byte[] sourcePort = new byte[8];

        /// <summary>
        /// Stores Destination Port Number
        /// </summary>
        public static byte[] destinationPort = new byte[8];

        /// <summary>
        /// Stores Destination Port Number during processing of TLS/SSL Fragments
        /// </summary>
        public static ushort TCPSrcPort;
        
        /// <summary>
        /// Stores Destination Port Number during processing of TLS/SSL Fragments
        /// </summary>
        public static ushort TCPDstPort;

        #endregion

        #region Variables to compute and store Keys

        /// <summary>
        /// to store Client Random Number
        /// </summary>
        public static byte[] clientRandomNumber = new byte[32];

        /// <summary>
        /// To store Server Random Number
        /// </summary>
        public static byte[] serverRandomNumber = new byte[32];

        /// <summary>
        /// To store PreMaster Secret key.
        /// </summary>
        public static byte[] preMasterSecret;

        /// <summary>
        /// To store Master Secret Key.
        /// </summary>
        public static byte[] masterSecretKey;

        /// <summary>
        /// To store Key Block Data.
        /// </summary>
        public static byte[] keyBlock;

        /// <summary>
        /// to store IV which is calculated from last 16 bytes of  previous cipher text. 
        /// </summary>
        public static byte[] clientCipherDataIV;

        /// <summary>
        /// to store IV which is calculated from last 16 bytes of  previous cipher text. 
        /// </summary>
        public static byte[] serverCipherDataIV;

        /// <summary>
        /// Byte array to hold clientMacWriteKey.
        /// </summary>
        public static byte[] clientMacWriteKey;

        /// <summary>
        /// Byte array to hold serverMacWriteKey.
        /// </summary>
        public static byte[] serverMacWriteKey;

        /// <summary>
        /// Byte array to hold clientWriteKey.
        /// </summary>
        public static byte[] clientWriteKey;

        /// <summary>
        /// Byte array to hold serverWriteKey.
        /// </summary>
        public static byte[] serverWriteKey;

        /// <summary>
        /// challenge data from client for ssl 2.0
        /// </summary>
        public static byte[] sslv2ChallengeData;

        /// <summary>
        /// Connection Id from server for ssl 2.0
        /// </summary>
        public static byte[] sslv2ConnectionId;

        /// <summary>
        /// client key exchange data for ssl 2.0
        /// </summary
        public static byte[] sslv2clientKeyExchange;

        #endregion

        /// <summary>
        /// True, if certificate password is mismatched
        /// </summary>
        public static bool passwordMismatch;

        /// <summary>
        /// True, if certificate is incorrect
        /// </summary>
        public static bool incorrectCertificate;       

        /// <summary>
        /// Stores the Selected Cipher Suite.
        /// </summary>
        public static CipherSuite selectedCipherSuite;

        /// <summary>
        /// Stores the status message to update UI
        /// </summary>
        public static string statusMessage = string.Empty;

        /// <summary>
        /// to store Client sequence number
        /// </summary>
        public static ulong clientSequenceNumber;

        /// <summary>
        /// to store Server sequence number
        /// </summary>
        public static ulong serverSequenceNumber;

        /// <summary>
        /// to store Client TCP Sequence number
        /// </summary>
        public static ulong clientTcpSequenceNumber = 0x0000000000000000;

        /// <summary>
        /// to store Server TCP Sequence number
        /// </summary>
        public static ulong serverTcpSequenceNumber = 0x4000000000000000;

        /// <summary>
        /// to store ContentType value.
        /// </summary>
        public static byte contentType;

        /// <summary>
        /// to indicate if new random number set is available.
        /// </summary>
        public static bool isClientKeyExchange;

        /// <summary>
        /// to indicate if frame is verified.
        /// </summary>
        public static bool isMacVerified;

        /// <summary>
        /// Previous Original Frame Number
        /// </summary>
        public static long previousFrameNumber = -1;

        /// <summary>
        /// Stores fid incase a packet 
        /// contains multiple encrypted messages.
        /// </summary>
        public static uint nextFid;

        /// <summary>
        /// byte array to hold Client application data while decrypting by RC4 
        /// application data.
        /// </summary>
        public static byte[] rc4ClientEncryptedData;

        /// <summary>
        /// byte array to hold Server application data while decrypting by RC4 
        /// application data.
        /// </summary>
        public static byte[] rc4ServerEncryptedData;

        /// <summary>
        /// to store encrypted application data.
        /// </summary>
        public static byte[] encryptedApplicationData;

        /// <summary>
        /// to store decrypted application data.
        /// </summary>
        public static byte[] decryptedApplicationData;

        /// <summary>
        /// to store Multiple decrypted application data.
        /// </summary>
        public static byte[] multipleApplicationData;       

        /// <summary>
        /// to store the padding value in SSLv2.
        /// </summary>
        public static byte sslv2Padding;

        /// <summary>
        /// to store session ID of client
        /// </summary>
        public static byte[] clientSessionID = null;

        /// <summary>
        /// to store session ID of server
        /// </summary>
        public static byte[] serverSessionID = null;

        /// <summary>
        /// Structure for SSL Version.
        /// </summary>
        public struct SSLVersion
        {
            /// <summary>
            /// Major Version.
            /// </summary>
            public int Major;

            /// <summary>
            /// Minor Version.
            /// </summary>
            public int Minor;
        }

        /// <summary>
        /// Structure to store Cipher Suite Information.
        /// </summary>
        public struct CipherSuiteInfo
        {
            /// <summary>
            /// SSL Version.
            /// </summary>
            public SSLVersion SslVersion;

            /// <summary>
            /// Key Exchange Algorithm.
            /// </summary>
            public KeyExchangeAlgorithm KeyExchangeAlg;

            /// <summary>
            /// Data Encryption Method.
            /// </summary>
            public DataEncryptionMethod DataEncryption;

            /// <summary>
            /// The MAC type
            /// </summary>
            public MAC MacType;

            /// <summary>
            /// Cipher Mode
            /// </summary>
            public CipherMode CipherMode;

            /// <summary>
            /// Bit-String size of Cipher;
            /// </summary>
            public CipherBlockSize BlockSize;

            /// <summary>
            /// Bit-String size of Cipher;
            /// </summary>
            public bool isSSLV2Selector;
        }

        /// <summary>
        ///  TCP Conversation ID that could be used to save state in the future.
        /// </summary>
        public static UInt64 TCPID;

        /// <summary>
        ///  Flagged true when the applicaiton data doens't matchthe length specified.
        /// </summary>
        public static bool SSLTLSLayerIsFragmented = false;

        /// <summary>
        /// Stores reassembly payload when it spans over multiple TCP reassembled fragments.
        /// </summary>
        public static byte[] SSLTLSReassemblyPayload = null;

        /// <summary>
        ///  Flagged true when the we start with a fragmented TLSSSL packet.
        /// </summary>
        public static bool SSLTLSPayloadHeaderMissing = false;

        /// <summary>
        ///  Remember the TCP Payload offset when we encounter it.
        /// </summary>
        public static uint TCPPayloadOffset = 0;

        /// <summary>
        ///  Remember the Reassembly Payload Length.
        /// </summary>
        public static uint ReassemblyPayloadLength = 0;

        /// <summary>
        ///  Remember the Reassembly Payload Length.
        /// </summary>
        public static uint TLSSSLUnassignedPayloadTotal = 0;
        
        /// <summary>
        ///  Remember the Reassembly Payload Length.
        /// </summary>
        public static uint LastTLSRecordLength = 0;

        /// <summary>
        ///  Reassembly Payload Header Length.
        /// </summary>
        public static uint PayloadHeaderLen = 0;
    }
}